package com.wenx.v3system.modular.cloud.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wenx.v3core.error.BusinessException;
import com.wenx.v3system.modular.cloud.domain.dto.SysPermissionDto;
import com.wenx.v3system.modular.cloud.domain.maps.SysPermissionMap;
import com.wenx.v3system.modular.cloud.domain.po.SysPermission;
import com.wenx.v3system.modular.cloud.domain.query.SysPermissionQuery;
import com.wenx.v3system.modular.cloud.mapper.SysPermissionMapper;
import com.wenx.v3system.modular.cloud.service.SysPermissionRestService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 系统权限RestService实现类
 * 继承ServiceImpl并实现BaseRestService接口
 *
 * @author wenx
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysPermissionRestServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements SysPermissionRestService {

    @Override
    public IPage<?> page(SysPermissionQuery query) {
        // 创建分页对象
        Page<SysPermission> page = new Page<>(query.getCurrent(), query.getSize());

        // 构建查询条件
        LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<SysPermission>()
                .like(StringUtils.hasText(query.getName()), SysPermission::getName, query.getName())
                .like(StringUtils.hasText(query.getCode()), SysPermission::getCode, query.getCode())
                .eq(StringUtils.hasText(query.getType()), SysPermission::getType, query.getType())
                .eq(StringUtils.hasText(query.getStatus()), SysPermission::getStatus, query.getStatus())
                .orderByAsc(SysPermission::getSort)
                .orderByDesc(SysPermission::getCreateTime);

        // 执行分页查询
        IPage<SysPermission> result = super.page(page, wrapper);

        // 手动转换为DTO，避免Java 17+模块系统反射访问问题
        Page<SysPermissionDto> dtoPage = new Page<>(result.getCurrent(), result.getSize(), result.getTotal());
        List<SysPermissionDto> dtoList = result.getRecords().stream()
                .map(this::convertToDto)
                .collect(Collectors.toList());
        dtoPage.setRecords(dtoList);
        
        return dtoPage;
    }

    @Override
    public Object get(Serializable id) {
        SysPermission permission = super.getById(id);
        return permission != null ? convertToDto(permission) : null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(SysPermissionDto dto) {
        // 参数校验
        if (!StringUtils.hasText(dto.getCode())) {
            throw new BusinessException("权限编码不能为空");
        }
        if (!StringUtils.hasText(dto.getName())) {
            throw new BusinessException("权限名称不能为空");
        }

        // 检查编码是否已存在
        if (existsByCode(dto.getCode(), null)) {
            throw new BusinessException("权限编码已存在: " + dto.getCode());
        }

        SysPermission permission = SysPermissionMap.INSTANCE.toPo(dto);
        super.save(permission);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Serializable id) {
        SysPermission permission = super.getById(id);
        if (permission == null) {
            throw new BusinessException("权限不存在，ID: " + id);
        }

        // 检查是否有子权限
        LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<SysPermission>()
                .eq(SysPermission::getParentId, id);
        if (super.count(wrapper) > 0) {
            throw new BusinessException("存在子权限，无法删除");
        }

        super.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysPermissionDto dto) {
        if (dto.getId() == null) {
            throw new BusinessException("权限ID不能为空");
        }

        SysPermission existingPermission = super.getById(dto.getId());
        if (existingPermission == null) {
            throw new BusinessException("权限不存在，ID: " + dto.getId());
        }

        // 检查编码是否已存在（排除自己）
        if (StringUtils.hasText(dto.getCode()) && existsByCode(dto.getCode(), dto.getId().toString())) {
            throw new BusinessException("权限编码已存在: " + dto.getCode());
        }

        SysPermission permission = SysPermissionMap.INSTANCE.toPo(dto);
        super.updateById(permission);
    }


    @Override
    public List<SysPermissionDto> getPermissionTree(String type, String status) {
        QueryWrapper<SysPermission> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasText(type)) {
            queryWrapper.eq("type", type);
        }
        if (StringUtils.hasText(status)) {
            queryWrapper.eq("status", status);
        }
        queryWrapper.orderByAsc("sort");

        List<SysPermission> permissions = super.list(queryWrapper);
        List<SysPermissionDto> dtoList = SysPermissionMap.INSTANCE.toDtoList(permissions);

        // 构建树形结构
        return buildTree(dtoList, null);
    }

    @Override
    public List<SysPermissionDto> getMenuTree() {
        return getPermissionTree("1", "1"); // 类型1为菜单，状态1为启用
    }

    @Override
    public List<SysPermissionDto> getMenuAll() {
        List<SysPermission> permissions = super.list();
        return SysPermissionMap.INSTANCE.toDtoList(permissions);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void movePermission(String permissionId, String targetParentId, Integer targetSort) {
        SysPermission permission = super.getById(permissionId);
        if (permission == null) {
            throw new BusinessException("权限不存在");
        }

        permission.setParentId(StringUtils.hasText(targetParentId) ? Long.valueOf(targetParentId) : null);
        permission.setSort(targetSort != null ? targetSort.longValue() : null);

        if (!super.updateById(permission)) {
            throw new BusinessException("移动权限失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdateSort(List<Map<String, Object>> sortData) {
        if (sortData == null || sortData.isEmpty()) {
            return;
        }

        for (Map<String, Object> data : sortData) {
            String id = String.valueOf(data.get("id"));
            Integer sort = (Integer) data.get("sort");

            SysPermission permission = super.getById(id);
            if (permission != null) {
                permission.setSort(sort != null ? sort.longValue() : null);
                super.updateById(permission);
            }
        }
    }

    @Override
    public boolean existsByCode(String code, String excludeId) {
        if (!StringUtils.hasText(code)) {
            return false;
        }

        LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<SysPermission>()
                .eq(SysPermission::getCode, code);

        if (StringUtils.hasText(excludeId)) {
            wrapper.ne(SysPermission::getId, excludeId);
        }

        return super.count(wrapper) > 0;
    }

    @Override
    public List<SysPermissionDto> getChildPermissions(String parentId) {
        LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<>();

        if (StringUtils.hasText(parentId)) {
            wrapper.eq(SysPermission::getParentId, parentId);
        } else {
            wrapper.isNull(SysPermission::getParentId);
        }

        wrapper.orderByAsc(SysPermission::getSort);

        List<SysPermission> permissions = super.list(wrapper);
        return SysPermissionMap.INSTANCE.toDtoList(permissions);
    }

    /**
     * 转换为DTO
     */
    private SysPermissionDto convertToDto(SysPermission permission) {
        if (permission == null) {
            return null;
        }
        return SysPermissionMap.INSTANCE.toDto(permission);
    }

    /**
     * 构建树形结构
     */
    private List<SysPermissionDto> buildTree(List<SysPermissionDto> permissions, Long parentId) {
        return permissions.stream()
                .filter(permission -> {
                    if (parentId == null) {
                        return permission.getParentId() == null;
                    }
                    return parentId.equals(permission.getParentId());
                })
                .map(permission -> {
                    permission.setChildren(buildTree(permissions, permission.getId()));
                    return permission;
                })
                .collect(Collectors.toList());
    }
}